#include "client.h"

RabinClient::RabinClient(char* host, int32_t port)
{	
	socket = new Socket();
	conn_succ = socket->Connect(host,port);	
}  
  
RabinClient::~RabinClient()
{
	delete socket;
}

CipherMessage* RabinClient::createHint(const Message* msg,const ClientKey* cliKey,const ServerPublicKey* pubKey)
{	
	return cliKey->coencrypt(msg,pubKey);                    
}  

Message* RabinClient::getMessage(const CipherMessage* msg,const ClientKey* cliKey) 
{	
	return cliKey->decrypt(msg); 
}  

bool RabinClient::get_conn_succ() 
{
	return conn_succ;
}

Message* RabinClient::get(uint32_t n)
{	
    // 1-2 OT Step 2
	ServerPublicKey* pubKey = 
      ServerPublicKey::fromRaw(socket->Receive());	
	
    // 1-2 OT Step 3
    MessageCollection* colTmp = 
      MessageCollection::fromRaw(socket->Receive());	

    if (colTmp->getSize() <= n) {
      delete colTmp;
      delete pubKey;
      return 0;
    }

    // 1-2 OT Step 4
    ClientKey* cliKey = ClientKey::fromRandom();	

    // 1-2 OT Step 5
    CipherMessage* chint = createHint(colTmp->get(n), cliKey, pubKey);
	socket->Send(chint->getSerialization());	

    // 1-2 OT Step 7
    CipherMessageCollection* colCipher = 
      CipherMessageCollection::fromRaw(socket->Receive());	

    // 1-2 OT Step 8
    Message* msg = getMessage(colCipher->get(n), cliKey);
	
	delete colCipher;
    delete chint;
    delete cliKey;
    delete colTmp;
    delete pubKey;
    
    return msg;
}